﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace mapxp.gui
{
    public partial class CrossView : Form
    {
        List<My_Point> v1 = mapxp.algorithem.ALgo_test.v1; //v1 is with no relative height 
        double height_p1 = 0;//mapxp.algorithem.ALgo_test.height_p1;
        double height_p2 = 0;//mapxp.algorithem.ALgo_test.height_p2;
        PointF[] pointsArray;//x is x, y is z 
        Pen blackPen = Pens.Black;
        Pen redPen = Pens.Red;
        Pen DarkVioletPen = Pens.DarkViolet;
        Pen brown = Pens.Brown;
        Brush myBrush = Brushes.Blue;
        Brush myMaroonBrush = Brushes.Maroon;
        int xPanleSize = 650;
        int yPanleSize = 620;
        int xStartFrom = 33;
        float NY =8;//the factor to mult in it 

        #region create labels
        //x labels
        Label label1 = new Label();
        Label label2 = new Label();
        Label label3 = new Label();
        Label label4 = new Label();
        Label label5 = new Label();
        Label label6 = new Label();
        Label label7 = new Label();
        Label label8 = new Label();
        Label label9 = new Label();
        Label label10 = new Label();
        Label label21 = new Label();//add in case there is more then 10 points
        Label label22 = new Label();//add in case there is more then 10 points
        //y labels
        Label label11 = new Label();
        Label label12 = new Label();
        Label label13 = new Label();
        Label label14 = new Label();
        Label label15 = new Label();
        Label label16 = new Label();
        Label label17 = new Label();
        Label label18 = new Label();
        Label label19 = new Label();
        Label label20 = new Label();
        Label label23 = new Label();
        Label label24 = new Label();
        #endregion

        public CrossView()
        {
            InitializeComponent();
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            
            pointsArray = changeFromMyPointArrayToASimplePointArray(v1);
            List<My_Point> Rtmp = v1;
            Rtmp[0].set_z_value(Rtmp[0].z_value()+height_p1);
            Rtmp[Rtmp.Count - 1].set_z_value(Rtmp[Rtmp.Count - 1].z_value() + height_p2);
            PointF[] newMyPoint = changeCordinate(pointsArray);
            PointF[] RedLineTmp = changeFromMyPointArrayToASimplePointArray(Rtmp);
            PointF[] RedLine = changeCordinate(RedLineTmp);

            Graphics G = e.Graphics;
            G.DrawLine(blackPen, xStartFrom, 5, 33, 620);// Y pivot
            G.DrawLine(blackPen, xStartFrom, 620, 650, 620);// X pivot
            
           // G.DrawLine(redPen, newMyPoint[0], newMyPoint[newMyPoint.Length - 1]);
           // System.Console.WriteLine("newMyPoint[0].Y= " + newMyPoint[0].Y);
            G.DrawLine(redPen, RedLine[0], RedLine[RedLine.Length - 1]);
            System.Console.WriteLine("RedLine[0].Y= " + RedLine[0].Y);
            //System.Console.WriteLine("###GUI###");
            //System.Console.WriteLine("newMyPoint[0].X=" + newMyPoint[0].X + "  newMyPoint[0].Y= " + newMyPoint[0].Y);

            G.DrawLines(DarkVioletPen, newMyPoint); // draws the line between all the points
            for (int i = 0; i < newMyPoint.Length; i = i + 1) // draws for every point a blue circle
            {
                G.FillEllipse(myBrush, newMyPoint[i].X - 2, newMyPoint[i].Y - 2, 5, 5);
            }

            #region lables
            //we need to set all width and Height of all labels
            #region labels_width_height
            label1.Width = 32;
            label1.Height = 20;

            label2.Width = 32;
            label2.Height = 20;

            label3.Width = 32;
            label3.Height = 20;

            label4.Width = 32;
            label4.Height = 20;

            label5.Width = 32;
            label5.Height = 20;

            label6.Width = 32;
            label6.Height = 20;

            label7.Width = 32;
            label7.Height = 20;

            label8.Width = 32;
            label8.Height = 20;

            label9.Width = 32;
            label9.Height = 20;

            label10.Width = 32;
            label10.Height = 20;

            label11.Width = 32;
            label11.Height = 20;

            label12.Width = 32;
            label12.Height = 20;

            label13.Width = 32;
            label13.Height = 20;

            label14.Width = 32;
            label14.Height = 20;

            label15.Width = 32;
            label15.Height = 20;

            label16.Width = 32;
            label16.Height = 20;

            label17.Width = 32;
            label17.Height = 20;

            label18.Width = 32;
            label18.Height = 20;

            label19.Width = 32;
            label19.Height = 20;

            label20.Width = 32;
            label20.Height = 20;

            label21.Width = 32;
            label21.Height = 20;

            label22.Width = 32;
            label22.Height = 20;

            label23.Width = 32;
            label23.Height = 20;
            #endregion

            label1.Location = new Point(20, yPanleSize + 10);// the 0,0 place
            label1.Text = pointsArray[0].X + "";// +"," + realPoints[0].Y;//the 0,0 lable real text
            label10.Location = new Point(628, yPanleSize + 10);// the 640,0 place
            label10.Text = pointsArray[pointsArray.Length - 1].X + "";// +"," + realPoints[realPoints.Length - 1].Y;//the 640,0 lable real text
          
            // not active for now
            #region case of less ten points in the list to paint
            if (newMyPoint.Length <= 10)
            {
                if (newMyPoint.Length.Equals(10))
                {   //x label
                    label9.Text = pointsArray[8].X + "";
                    label9.Location = new Point(Convert.ToInt32(newMyPoint[8].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[8].X, yPanleSize - 2, 5, 5);
               

                }
                if (newMyPoint.Length >= 9)
                {//x label
                    label8.Text = pointsArray[7].X + "";
                    label8.Location = new Point(Convert.ToInt32(newMyPoint[7].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[7].X, yPanleSize - 2, 5, 5);
 
                }
                if (newMyPoint.Length >= 8)
                {
                    //x label
                    label7.Text = pointsArray[6].X + "";
                    label7.Location = new Point(Convert.ToInt32(newMyPoint[6].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[7].X, yPanleSize - 2, 5, 5);

                }
                if (newMyPoint.Length >= 7)
                {
                    //x label
                    label6.Text = pointsArray[5].X + "";
                    label6.Location = new Point(Convert.ToInt32(newMyPoint[5].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[5].X, yPanleSize - 2, 5, 5);

                }
                if (newMyPoint.Length >= 6)
                {
                    //x label
                    label5.Text = pointsArray[4].X + "";
                    label5.Location = new Point(Convert.ToInt32(newMyPoint[4].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[4].X, yPanleSize - 2, 5, 5);

                }
                if (newMyPoint.Length >= 5)
                {
                    //x label
                    label4.Text = pointsArray[3].X + "";
                    label4.Location = new Point(Convert.ToInt32(newMyPoint[3].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[3].X, yPanleSize - 2, 5, 5);

                }
                if (newMyPoint.Length >= 4)
                {
                    //x label
                    label3.Text = pointsArray[2].X + "";
                    label3.Location = new Point(Convert.ToInt32(newMyPoint[2].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[2].X, yPanleSize - 2, 5, 5);

                }
                if (newMyPoint.Length >= 3)
                {
                    //x label
                    label2.Text = pointsArray[1].X + "";
                    label2.Location = new Point(Convert.ToInt32(newMyPoint[1].X) - 10, yPanleSize + 10);
                    G.FillEllipse(myBrush, newMyPoint[1].X, yPanleSize - 2, 5, 5);
                }
            }
            #endregion

            #region case of more then ten points in the list to paint
            else
            {//the size of the panel divide by 10
                double distFromXStartToEnd = pointsArray[pointsArray.Length - 1].X - pointsArray[0].X;
                double XJumps = distFromXStartToEnd / 10;
                double Xplace = (xPanleSize - 30) / 10;

                double maxZValue = pointsArray[0].Y;
                double minZValue = pointsArray[0].Y;
                //we need to find the bigest Z value
                for (int i = 1; i < pointsArray.Length; i = i + 1)
                {
                    if (pointsArray[i].Y > maxZValue)
                    {
                        maxZValue = pointsArray[i].Y;
                    }
                    if (pointsArray[i].Y < minZValue)
                    {
                        minZValue = pointsArray[i].Y;
                    }
                }
                double minusYValue = 0;
                if (minZValue < 0)
                {
                    minusYValue = minZValue;
                }

                //double YJumps = (maxZValue - minZValue) / 10;
                //double Yplace = (yPanleSize - 50) / 10;
                int YJumps = 8;
                //x label
                label21.Text = XJumps + pointsArray[0].X + "";
                label21.Location = new Point(Convert.ToInt32(Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToInt64(Xplace + 30), yPanleSize - 2, 5, 5);
                ////y label
                label19.Text =  minZValue + "";
                label19.Location = new Point(0, yPanleSize);
                label11.Text = YJumps + minZValue + "";
               // label11.Location = new Point(0, (int)(570 - ((pointsArray[1].Y - minZValue) * NY)-10));
                //G.FillEllipse(myMaroonBrush, 30, (int)(570 - ((pointsArray[1].Y - minZValue) * NY)) - 2, 5, 5);
                int tmp = (int)((pointsArray[1].Y - minZValue) * NY + (NY*1.5));
                label11.Location = new Point(0, (yPanleSize - tmp) );
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp) , 5, 5);

                //x label
                label3.Text = 2 * XJumps + pointsArray[0].X + "";
                label3.Location = new Point(Convert.ToInt32(2 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, (float)(2 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label12.Text = 2* YJumps + minZValue + "";
                label12.Location = new Point(0, (yPanleSize - tmp * 2) );
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 2) , 5, 5);
                //label12.Location = new Point(0, (570 - tmp*2) );
                //G.FillEllipse(myMaroonBrush, 30, (570 - tmp* 2), 5, 5);
                //x label
                label4.Text = 3 * XJumps + pointsArray[0].X + "";
                label4.Location = new Point(Convert.ToInt32(3 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(3 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label13.Text = 3 * YJumps + minZValue + "";
                label13.Location = new Point(0, (yPanleSize - tmp * 3) );
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 3) , 5, 5);
                //label13.Location = new Point(0, (570 - tmp * 4));
                //G.FillEllipse(myMaroonBrush, 30, (570 - tmp * 4), 5, 5);
                //x label
                label5.Text = 4 * XJumps + pointsArray[0].X + "";
                label5.Location = new Point(Convert.ToInt32(4 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(4 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label14.Text = 4 * YJumps + minZValue + "";
                label14.Location = new Point(0, (yPanleSize - tmp * 4) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 4) - 2, 5, 5);
                //x label
                label6.Text = 5 * XJumps + pointsArray[0].X + "";
                label6.Location = new Point(Convert.ToInt32(5 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(5 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label15.Text = 5 * YJumps + minZValue + "";
                label15.Location = new Point(0, (yPanleSize - tmp * 5) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 5) - 2, 5, 5);
                //x label
                label7.Text = 6 * XJumps + pointsArray[0].X + "";
                label7.Location = new Point(Convert.ToInt32(6 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(6 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label16.Text = 6 * YJumps + minZValue + "";
                label16.Location = new Point(0, (yPanleSize - tmp * 6) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 6) - 2, 5, 5);
                //x label
                label8.Text = 7 * XJumps + pointsArray[0].X + "";
                label8.Location = new Point(Convert.ToInt32(7 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(7 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label17.Text = 7 * YJumps + minZValue + "";
                label17.Location = new Point(0, (yPanleSize - tmp * 7) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 7) - 2, 5, 5);
                //x label
                label9.Text = 8 * XJumps + pointsArray[0].X + "";
                label9.Location = new Point(Convert.ToInt32(8 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(8 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label18.Text = 8 * YJumps + minZValue + "";
                label18.Location = new Point(0, (yPanleSize - tmp * 8) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 8) - 2, 5, 5);
                //x label
                label22.Text = 9 * XJumps + pointsArray[0].X + "";
                label22.Location = new Point(Convert.ToInt32(9 * Xplace + 30 - 10), yPanleSize + 10);
                G.FillEllipse(myMaroonBrush, Convert.ToUInt64(9 * Xplace + 30), yPanleSize - 2, 5, 5);
                //y label
                label23.Text = 9 * YJumps + minZValue + "";
                label23.Location = new Point(0, (yPanleSize - tmp * 9) - 10);
                G.FillEllipse(myMaroonBrush, 30, (yPanleSize - tmp * 9) - 2, 5, 5);
                
            }
            #endregion
      
            #region label_add_to_panel
            panel1.Controls.Add(label1);
            panel1.Controls.Add(label2);
            panel1.Controls.Add(label3);
            panel1.Controls.Add(label4);
            panel1.Controls.Add(label5);
            panel1.Controls.Add(label6);
            panel1.Controls.Add(label7);
            panel1.Controls.Add(label8);
            panel1.Controls.Add(label9);
            panel1.Controls.Add(label10);
            panel1.Controls.Add(label11);
            panel1.Controls.Add(label12);
            panel1.Controls.Add(label13);
            panel1.Controls.Add(label14);
            panel1.Controls.Add(label15);
            panel1.Controls.Add(label16);
            panel1.Controls.Add(label17);
            panel1.Controls.Add(label18);
            panel1.Controls.Add(label19);
            panel1.Controls.Add(label20);
            panel1.Controls.Add(label21);
            panel1.Controls.Add(label22);
            panel1.Controls.Add(label23);
            panel1.Controls.Add(label24);
            #endregion

            #endregion

        }


        #region public methods
        /// <summary>
        /// This method gets a list of My_Point and makes an c# Point array.
        /// The X value of each point in the ans point array represent the x value of each point in the My_Point
        /// array that was given compatibly.
        /// The Y value of each Point in the ans point array represent the Z value of each point in the My_Point
        /// array that was given compatibly.
        /// </summary>
        /// <param name="myPoint">this is a My_Point element</param>
        /// <returns>C# Point array. ans[i].X = My_Point[i].x_value, ans[i].Y = My_Point[i].z_value  </returns>
        public PointF[] changeFromMyPointArrayToASimplePointArray(List<My_Point> myPoint)
        {
            PointF[] ansPointArray = new PointF[myPoint.Count];
            for (int i = 0; i < myPoint.Count; i++)
            {
                ansPointArray[i] = new PointF((float)(myPoint[i].x_value()),
                                              (float)(myPoint[i].z_value()));
            }

            return ansPointArray;
        }

        /// <summary>
        /// This methodcopys the values of the real map points to an inner arrayand
        /// changes the cordinate of the map real value  to the size of
        /// this specific window. 
        /// </summary>
        /// <param name="myPoints">C# Point array. ans[i].X = My_Point[i].x_value, ans[i].Y = My_Point[i].z_value </param>
        /// <returns>array of points ready to be painted</returns>
        public PointF[] changeCordinate(PointF[] myPoints)
        {
            PointF[] ansPoints = new PointF[myPoints.Length];
            float maxZValue = myPoints[0].Y;
            float minZValue = myPoints[0].Y;
            //we need to find the bigest Z value
            for (int i = 1; i < myPoints.Length; i = i + 1)
            {
                if (myPoints[i].Y > maxZValue)
                {
                    maxZValue = myPoints[i].Y;
                }
                if (myPoints[i].Y < minZValue)
                {
                    minZValue = myPoints[i].Y;
                }
            }
            float minusYValue = 0;
            if (minZValue < 0)
            {
                minusYValue = minZValue;
            }
            float newXZero = myPoints[0].X;
            float distFromYStartToEnd = maxZValue - minZValue;

            float YRatio = (yPanleSize - 50) / distFromYStartToEnd;//-50 so the max point wont be at top of chart
           // System.Diagnostics.Debug.WriteLine("maxZValue= " + maxZValue + "  minZValue= "+minZValue +
                             //     "  minusYValue= " + minusYValue);
            float distFromXStartToEnd = myPoints[myPoints.Length - 1].X - myPoints[0].X;
            float Xratio = (xPanleSize-33 )/ distFromXStartToEnd;

           // float NY = 8;  // the new yration  that will be canged by the button that will be on the panel
           // System.Diagnostics.Debug.WriteLine("new ans= " + (570 - ((myPoints[0].Y-minZValue)*NY)));

          //System.Diagnostics.Debug.WriteLine("YRatio = " + YRatio + "   yPanleSize = " + yPanleSize+
           //   "  distFromYStartToEnd  =" + distFromYStartToEnd + "  minusYValue= "+minusYValue);
          //System.Diagnostics.Debug.WriteLine("myPoints[0].Y= " + myPoints[0].Y);

          ansPoints[0] = new PointF(xStartFrom, (620 - ((myPoints[0].Y - minZValue) * NY))); //+ yLess
            ansPoints[myPoints.Length - 1] = new PointF(xPanleSize, (float)((yPanleSize - ((myPoints[myPoints.Length - 1].Y - minusYValue) * YRatio))));//+yLess

            //System.Diagnostics.Debug.WriteLine("ansPoints[0].x= " + ansPoints[0].X + "  ansPoints[0].y= " + ansPoints[0].Y);
            //System.Diagnostics.Debug.WriteLine("ansPoints[1].x= " + myPoints[1].X);
            //System.Diagnostics.Debug.WriteLine("xStartFrom = " + xStartFrom + " newXZero = " + newXZero + "  xratio= " + Xratio);
            //System.Diagnostics.Debug.WriteLine("myPoints[0].x= " + myPoints[0].X + "  myPoints[myPoints.Length-1].X= " + myPoints[myPoints.Length - 1].X +
            //                                        "  diff of xmax-xmin = " + (myPoints[myPoints.Length - 1].X - ansPoints[0].X));
            for (int i = 1; i < myPoints.Length ; i = i + 1)
            {
                ansPoints[i] = new PointF((float)(Xratio * ( myPoints[i].X - newXZero)+xStartFrom ), (620 - ((myPoints[i].Y - minZValue) * NY)));//(float)((yPanleSize - ((myPoints[i].Y - minusYValue) * YRatio)))
                 //System.Diagnostics.Debug.WriteLine("i= " + i + "  x= " + ansPoints[i].X + " y= " + ansPoints[i].Y);
                //System.Diagnostics.Debug.WriteLine("i= " + i + " y*8= " + ansPoints[i].Y + " y*80= " + (620 - ((myPoints[i].Y - minZValue) * 80)));

            }
            return ansPoints;
        }
        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            NY = NY + 5;
            Refresh();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            NY = NY - 5;
            Refresh();
        }
    }
}
